using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using WindowsGame1.CoreComponents;
using WindowsGame1.SpriteClasses;
using WindowsGame1.DialogClasses;
using System.Xml;
using System.Reflection;
using System.Collections.ObjectModel;
using WindowsGame1.ItemClasses;

namespace WindowsGame1
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        StartScreen startScreen;
        CreatePCScreen createPCScreen;
        HelpScreen helpScreen;
        ActionScreen actionScreen;
        CreditScreen creditScreen;
        IntroScreen introScreen;
        QuitGameScreen quitPopUpScreen;
        GenderPopUpScreen genderPopUpScreen;
        ClassPopUpScreen classPopUpScreen;
        DifficultyPopUpScreen difficultyPopUpScreen;
        InputScreen nameInputScreen;
        GameScreen activeScreen;
        ViewCharacterScreen viewCharacterScreen;
        CombatScreen combatScreen;
        TreasureScreen treasureScreen;
        GameOverScreen gameOverScreen;
        MonsterKillScreen monsterKillScreen;

        SpriteFont normalFont;
        Texture2D background;
        static KeyboardState newState;
        static KeyboardState oldState;

        PlayerCharacter playerCharacter;
        PlayerComponent player;
        AnimatedSprite playerSprite;
        List<Animation> playerAnimations = new List<Animation>();
        Texture2D[] playerTextures = new Texture2D[3];
        
        static Camera camera = new Camera();
        static SpriteBatch tileSpriteBatch;

        List<NPC> npcs = new List<NPC>();
        string[] assetNames =
        {
            @"Sprites\knt1",
            @"Sprites\nja1",
            @"Sprites\skl1"
        };
        Texture2D[] spriteTextures;
        Random random = new Random();
        bool inDialog;

        DialogComponent dialog;
        Script script;
        NPC dialogNPC = null;
        string[] dialogNames =
        {
            "KnightDialog",
            "NinjaDialog",
            "SkeletonDialog"
        };
        List<Animation> animations = new List<Animation>();
        List<Monster> monsters = new List<Monster>();

        ItemManager itemManager;

        private static SoundEffect backgroundMusic;
        private static Song mus;



        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            graphics.PreferredBackBufferWidth = 1024;
            graphics.PreferredBackBufferHeight = 768;
            graphics.PreferredBackBufferFormat = SurfaceFormat.Bgr32;
            graphics.IsFullScreen = false;
            this.Window.Title = "Shandray";
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            tileSpriteBatch = new SpriteBatch(GraphicsDevice);
            Services.AddService(typeof(SpriteBatch), spriteBatch);
            Services.AddService(typeof(ContentManager), Content);
            dialog = new DialogComponent(this);
            Components.Add(dialog);
            normalFont = Content.Load<SpriteFont>("normal");
            LoadMusic();
            LoadGameScreens();
            CreateAnimations();
            spriteTextures = new Texture2D[assetNames.Length];
            for (int i = 0; i < assetNames.Length; i++)
                spriteTextures[i] = Content.Load<Texture2D>(assetNames[i]);
            script = ReadScript(@"Content\script1.script");
            LoadPlayerSprites();
            CreatePlayerAnimations();
            CreateNPCS();
            CreateMonsters();
            CreateItemManager();

        }

        private void LoadMusic()
        {
            //I want there to be menu music and then game music.
            //one file will play during the action screen, and one will play during character 
            //selection, menu traversing, etc.
            //There also has to be combat music, but I think we'll add that in once we actually have...combat
            backgroundMusic = Content.Load<SoundEffect>(@"Sounds\Music3");
            mus = Content.Load<Song>(@"Sounds\m1");
        }

        private void CreateItemManager()
        {
            itemManager = new ItemManager(this);
            itemManager.SatelliteCollision +=
            new ItemManager.SatelliteCollisionEventHandler(satelliteManager_SatelliteCollision);
        }

        void satelliteManager_SatelliteCollision(object sender, SatelliteEventArgs e)
        {
            activeScreen.Enabled = false;
            activeScreen = treasureScreen;
            treasureScreen.Show(e.Satellite);
        }

        private void LoadGameScreens()
        {
            LoadGameOverScreen();
            LoadCreatePCScreen();
            LoadGenderPopUpScreen();
            LoadClassPopUpScreen();
            LoadDifficultyPopUpScreen();
            LoadNameInputScreen();
            LoadHelpScreen();
            LoadCreditScreen();
            LoadIntroScreen();
            LoadActionScreen();
            LoadViewCharacterScreen();
            //LoadCombatScreen();
            LoadStartScreen();
            LoadTreasureScreen();
            LoadMonsterKillScreen();
            LoadQuitPopUpScreen();
            
            //LoadQuitActionScreen();
            creditScreen.Hide();
            startScreen.Hide();
            helpScreen.Hide();
            createPCScreen.Hide();
            activeScreen = introScreen;
            activeScreen.Show();
        }

        private void LoadGameOverScreen()
        {
            gameOverScreen = new GameOverScreen(this);
            Components.Add(gameOverScreen);
            gameOverScreen.Hide();
        }

        private void LoadTreasureScreen()
        {
            treasureScreen = new TreasureScreen(this);
            Components.Add(treasureScreen);
            treasureScreen.Hide();
        }

        private void LoadMonsterKillScreen()
        {
            monsterKillScreen = new MonsterKillScreen(this);
            Components.Add(monsterKillScreen);
            monsterKillScreen.Hide();
        }

        private void LoadPlayerSprites()
        {
            playerTextures[0] = Content.Load<Texture2D>(@"Sprites\pirate");
            playerTextures[1] = Content.Load<Texture2D>(@"Sprites\bountyhunter");
            playerTextures[2] = Content.Load<Texture2D>(@"Sprites\slavetrader");
        }

        private void CreatePlayerAnimations()
        {
            Animation tempAnimation = new Animation(3, 64, 64, 0, 192);
            playerAnimations.Add(tempAnimation);
            tempAnimation = new Animation(3, 64, 64, 0, 0);
            playerAnimations.Add(tempAnimation);
            tempAnimation = new Animation(3, 64, 64, 0, 64);
            playerAnimations.Add(tempAnimation);
            tempAnimation = new Animation(3, 64, 64, 0, 128);
            playerAnimations.Add(tempAnimation);
        }

        private List<Animation> ClonePlayerAnimations()
        {
            List<Animation> newAnimation = new List<Animation>();
            foreach (Animation a in playerAnimations)
            {
                Animation clonedAnimation = (Animation)a.Clone();
                newAnimation.Add(clonedAnimation);
            }
            return newAnimation;
        }

        private Script ReadScript(string scriptName)
        {
            Script newScript;
            XmlDocument input = new XmlDocument();
            input.Load(scriptName);
            XmlNodeList dialogs = input.GetElementsByTagName("Dialog");
            Collection<Dialog> newDialogs = new Collection<Dialog>();
            foreach (XmlNode node in dialogs)
            {
                string name = "";
                string text = "";
                List<DialogHandler> handlers = new List<DialogHandler>();
                Dialog newDialog;
                foreach (XmlNode innerNode in node.ChildNodes)
                {
                    if (innerNode.Name == "Name")
                        name = innerNode.Attributes["Text"].Value;
                    if (innerNode.Name == "Text")
                        text = innerNode.InnerText;
                    if (innerNode.Name == "Handlers")
                    {
                        handlers = ReadHandlers(innerNode);
                    }
                }
                newDialog = new Dialog(name, text, handlers.ToArray());
                newDialogs.Add(newDialog);
            }
            Dialog[] dialogsToAdd = new Dialog[newDialogs.Count];
            for (int i = 0; i < newDialogs.Count; i++)
                dialogsToAdd[i] = newDialogs[i];
            newScript = new Script(dialogsToAdd);
            return newScript;
        }

        private List<DialogHandler> ReadHandlers(XmlNode innerNode)
        {
            List<DialogHandler> handlers = new List<DialogHandler>();
            foreach (XmlNode node in innerNode)
            {
                string text = "";
                string actions = "";
                if (node.Name == "Handler")
                {
                    text = node.Attributes["Text"].Value;
                    actions = node.Attributes["Actions"].Value;
                    List<DialogAction> dialogActions = new List<DialogAction>();
                    string[] methods = actions.Split(';');
                    string methodName = "";
                    object[] parameters = null;
                    foreach (string m in methods)
                    {
                        if (m.Contains(':'))
                        {
                            string[] newActions = m.Split(':');
                            methodName = newActions[0];
                            parameters = (object[])newActions[1].Split(',');
                        }
                        else
                        {
                            methodName = m;
                            parameters = null;
                        }
                        dialogActions.Add(new DialogAction(methodName, parameters));
                    }
                    DialogHandler handler = new DialogHandler(text,
                    (DialogAction[])dialogActions.ToArray());
                    handlers.Add(handler);
                }
            }
            return handlers;
        }

        private void CreateNPCS()
        {
            for (int i = 0; i < assetNames.Length; i++)
            {
                npcs.Add(
                new NPC(this,
                spriteTextures[i],
                CloneAnimations(),
                dialog,
                script));
                npcs[i].DialogName = dialogNames[i];
                npcs[i].IsAnimating = true;
                int direction = random.Next(0, 4);
                switch (direction)
                {
                    case 0:
                        npcs[i].CurrentAnimation = AnimationKey.Up;
                        break;
                    case 1:
                        npcs[i].CurrentAnimation = AnimationKey.Down;
                        break;
                    case 2:
                        npcs[i].CurrentAnimation = AnimationKey.Left;
                        break;
                    case 3:
                        npcs[i].CurrentAnimation = AnimationKey.Right;
                        break;
                }
                Vector2 position = new Vector2();
                position.X = TileEngine.TileWidth * random.Next(1, 10);
                position.Y = TileEngine.TileHeight * random.Next(1, 10);
                npcs[i].Position = position;
            }
        }

        private void LoadIntroScreen()
        {
            introScreen = new IntroScreen(this);
            Components.Add(introScreen);
        }

        private void LoadCreditScreen()
        {
            creditScreen = new CreditScreen(this);
            Components.Add(creditScreen);
        }

        private void LoadNameInputScreen()
        {
            background = Content.Load<Texture2D>(@"GUI\choosename");
            nameInputScreen = new InputScreen(this,
            normalFont,
            background,
            Content.Load<Texture2D>(@"GUI\buttonbackgroundshort"));
            Components.Add(nameInputScreen);
        }

        private void LoadDifficultyPopUpScreen()
        {
            difficultyPopUpScreen = new DifficultyPopUpScreen(this);
            Components.Add(difficultyPopUpScreen);
        }

        private void LoadClassPopUpScreen()
        {
            classPopUpScreen = new ClassPopUpScreen(this);
            Components.Add(classPopUpScreen);
        }

        private void LoadGenderPopUpScreen()
        {
            genderPopUpScreen = new GenderPopUpScreen(this);
            Components.Add(genderPopUpScreen);
            genderPopUpScreen.Hide();
        }

        private void LoadQuitPopUpScreen()
        {
            quitPopUpScreen = new QuitGameScreen(this);
            Components.Add(quitPopUpScreen);
            quitPopUpScreen.Hide();
        }

        private void LoadActionScreen()
        {
            actionScreen = new ActionScreen(this,normalFont,
                Content.Load<TileMap>(@"TileMaps\tilemap1"), "tileset1");
            Components.Add(actionScreen);
            actionScreen.Hide();
        }

        private void LoadHelpScreen()
        {
            helpScreen = new HelpScreen(this);
            Components.Add(helpScreen);
        }

        private void LoadCombatScreen()
        {
            combatScreen = new CombatScreen(this,playerCharacter);
            Components.Add(combatScreen);
            combatScreen.Hide();
        }

        private void LoadStartScreen()
        {
            startScreen = new StartScreen(this);
            Components.Add(startScreen);
        }

        private void LoadCreatePCScreen()
        {
            createPCScreen = new CreatePCScreen(this);
            Components.Add(createPCScreen);
        }

        private void LoadViewCharacterScreen()
        {
            viewCharacterScreen = new ViewCharacterScreen(this);
            Components.Add(viewCharacterScreen);
            viewCharacterScreen.Hide();
        }

        protected override void UnloadContent()
        {
        }

        protected override void Update(GameTime gameTime)
        {
            newState = Keyboard.GetState();

            if (inDialog && dialogNPC != null)
            {
                dialog.Show();
                dialogNPC.StartDialog(dialogNPC.DialogName);
                dialogNPC = null;
            }

            if (!dialog.Enabled)
                inDialog = false;

            if (activeScreen == startScreen)
            {
                HandleStartScreenInput();
            }
            else if (activeScreen == helpScreen)
            {
                HandleHelpScreenInput();
            }
            else if (activeScreen == createPCScreen)
            {
                HandleCreatePCScreenInput();
            }
            else if (activeScreen == quitPopUpScreen)
            {
                HandleQuitPopUpScreenInput();
            }
            else if (activeScreen == genderPopUpScreen)
            {
                HandleGenderPopUpScreenInput();
            }
            else if (activeScreen == classPopUpScreen)
            {
                HandleClassPopUpScreenInput();
            }
            else if (activeScreen == difficultyPopUpScreen)
            {
                HandleDifficultyPopUpScreenInput();
            }
            else if (activeScreen == nameInputScreen)
            {
                HandleNameInputScreenInput();
            }
            else if (activeScreen == introScreen)
            {
                HandleIntroScreenInput();
            }
            else if (activeScreen == creditScreen)
            {
                HandleCreditScreenInput();
            }
            else if (activeScreen == actionScreen)
            {
                HandleActionScreeenInput();
                HandlePlayerInput(gameTime);
            }
            else if (activeScreen == viewCharacterScreen)
            {
                HandleViewCharacterScreenInput();
            }
            else if (activeScreen == combatScreen)
            {
                HandleCombatScreenInput();
                HandleCombatMovement(gameTime);
            }
            else if (activeScreen == treasureScreen)
            {
                HandleTreasureScreenInput();
            }
            else if (activeScreen == monsterKillScreen)
            {
                HandleMonsterKillScreenInput();
            }
            else if (activeScreen == gameOverScreen)
            {
                HandleGameOverScreenInput();
            }
            base.Update(gameTime);
            oldState = newState;
            
        }

        private void HandleTreasureScreenInput()
        {
            if (CheckKey(Keys.Space)||CheckKey(Keys.Enter))
            {
                Satellite satellite = treasureScreen.Satellite;
                activeScreen.Hide();
                activeScreen = actionScreen;
                activeScreen.Show();
                playerCharacter.AddGold(satellite.Gold);
            }
        }

        private void HandleMonsterKillScreenInput()
        {
            if (CheckKey(Keys.Enter))
            {
                Monster monster = monsterKillScreen.Monster;
                activeScreen.Hide();
                activeScreen = actionScreen;
                activeScreen.Show();
                playerCharacter.AddGold(monster.Gold);
                playerCharacter.AddExperience(monster.Exp);
            }
        }

        private void HandleCombatScreenInput()
        {
            if (combatScreen.BattleOver)
            {
                combatScreen.End();
                combatScreen.Hide();
                if (!combatScreen.Won)
                {
                    activeScreen.Hide();
                    activeScreen = gameOverScreen;
                    activeScreen.Show();
                }
                else if (combatScreen.Won)
                {
                    activeScreen = actionScreen;
                    activeScreen.Show();
                    activeScreen.Enabled = false;
                    activeScreen = monsterKillScreen;
                    monsterKillScreen.Show(combatScreen.Monster);
                }
            }

            else if (CheckKey(Keys.Space))
            {
                combatScreen.createBall(true);
            }
        }

        


        private void HandlePlayerInput(GameTime gameTime)
        {
            player.Update(gameTime);
            if (!inDialog)
            {
                foreach (NPC npc in npcs)
                    npc.Update(gameTime);
                if (CheckAttackRadius(gameTime))
                    return;
                itemManager.Update(gameTime);
                itemManager.CheckSatelliteCollision(player.Origin);
                if (CheckKey(Keys.Enter) || CheckKey(Keys.Space))
                    CheckSpeakingRadius();
            }
            if (!inDialog)
                HandlePlayerMovement();
        }

       

        private void HandlePlayerMovement()
        {
            Vector2 motion = new Vector2();
            playerSprite.IsAnimating = true;
            if (newState.IsKeyDown(Keys.Up) || newState.IsKeyDown(Keys.NumPad8))
            {
                motion.Y--;
                playerSprite.CurrentAnimation = AnimationKey.Up;
            }
            if (newState.IsKeyDown(Keys.Down) || newState.IsKeyDown(Keys.NumPad2))
            {
                motion.Y++;
                playerSprite.CurrentAnimation = AnimationKey.Down;
            }
            if (newState.IsKeyDown(Keys.Right) || newState.IsKeyDown(Keys.NumPad6))
            {
                motion.X++;
                playerSprite.CurrentAnimation = AnimationKey.Right;
            }
            if (newState.IsKeyDown(Keys.Left) || newState.IsKeyDown(Keys.NumPad4))
            {
                motion.X--;
                playerSprite.CurrentAnimation = AnimationKey.Left;
            }
            if (newState.IsKeyDown(Keys.NumPad9))
            {
                motion.X++;
                motion.Y--;
                playerSprite.CurrentAnimation = AnimationKey.Right;
            }
            if (newState.IsKeyDown(Keys.NumPad3))
            {
                motion.X++;
                motion.Y++;
                playerSprite.CurrentAnimation = AnimationKey.Right;
            }
            if (newState.IsKeyDown(Keys.NumPad1))
            {
                motion.X--;
                motion.Y++;
                playerSprite.CurrentAnimation = AnimationKey.Left;
            }
            if (newState.IsKeyDown(Keys.NumPad7))
            {
                motion.X--;
                motion.Y--;
                playerSprite.CurrentAnimation = AnimationKey.Left;
            }
            if (motion != Vector2.Zero)
            {
                motion.Normalize();
                motion *= playerSprite.Speed;
                foreach (NPC npc in npcs)
                {
                    float distance = Vector2.Distance(
                    npc.Origin,
                    playerSprite.Origin + motion);
                    if (distance <= npc.CollisionRadius)
                        return;
                }
                if (!actionScreen.CheckUnWalkableTile(playerSprite.Bounds, motion))
                    playerSprite.Position += motion;
            }
            else
                playerSprite.IsAnimating = false;
            playerSprite.LockToMap();
            camera.LockToSprite(playerSprite);
            camera.LockCamera();
        }

        private void HandleCombatMovement(GameTime gameTime)
        {
            player.Update(gameTime);
            Vector2 motion = new Vector2();
            playerSprite.IsAnimating = true;
            if (newState.IsKeyDown(Keys.Up) || newState.IsKeyDown(Keys.NumPad8))
            {
                motion.Y--;
                playerSprite.CurrentAnimation = AnimationKey.Up;
            }
            if (newState.IsKeyDown(Keys.Down) || newState.IsKeyDown(Keys.NumPad2))
            {
                motion.Y++;
                playerSprite.CurrentAnimation = AnimationKey.Down;
            }
            if (newState.IsKeyDown(Keys.Right) || newState.IsKeyDown(Keys.NumPad6))
            {
                motion.X++;
                playerSprite.CurrentAnimation = AnimationKey.Right;
            }
            if (newState.IsKeyDown(Keys.Left) || newState.IsKeyDown(Keys.NumPad4))
            {
                motion.X--;
                playerSprite.CurrentAnimation = AnimationKey.Left;
            }
            if (newState.IsKeyDown(Keys.NumPad9))
            {
                motion.X++;
                motion.Y--;
                playerSprite.CurrentAnimation = AnimationKey.Right;
            }
            if (newState.IsKeyDown(Keys.NumPad3))
            {
                motion.X++;
                motion.Y++;
                playerSprite.CurrentAnimation = AnimationKey.Right;
            }
            if (newState.IsKeyDown(Keys.NumPad1))
            {
                motion.X--;
                motion.Y++;
                playerSprite.CurrentAnimation = AnimationKey.Left;
            }
            if (newState.IsKeyDown(Keys.NumPad7))
            {
                motion.X--;
                motion.Y--;
                playerSprite.CurrentAnimation = AnimationKey.Left;
            }
            if (motion != Vector2.Zero)
            {
                motion.Normalize();
                motion *= playerSprite.Speed;
                playerSprite.Position += motion;
            }
            else
                playerSprite.IsAnimating = false;
            playerSprite.LockToCombatScreen();
            camera.LockToSprite(playerSprite);
            camera.LockCamera();
        }

        private void CheckSpeakingRadius()
        {
            foreach (NPC npc in npcs)
            {
                float distance = Vector2.Distance(
                npc.Origin,
                playerSprite.Origin);
                if (distance < npc.SpeakingRadius)
                {
                    //dialog.Show();
                    //npc.StartDialog(npc.DialogName);
                    dialogNPC = npc;
                    inDialog = true;
                    break;
                }
            }
        }

        private bool CheckAttackRadius(GameTime gameTime)
        {
            foreach (Monster monster in monsters)
            {
                if (!monster.InCombat)
                {
                    monster.Update(gameTime);
                    float distance = Vector2.Distance(
                    monster.Origin,
                    playerSprite.Origin);
                    if (distance < monster.AttackRadius)
                    {
                        activeScreen.Hide();

                        //The combat screen is loaded here because I needed the combat screen to change the HP
                        //of the player character and the player character did not exist when the initial screens
                        //were being loaded.
                        LoadCombatScreen();
                        
                        activeScreen = combatScreen;
                        combatScreen.Begin(
                        Content.Load<Texture2D>(@"Backgrounds\combatbackground"),
                        player,
                        monster);
                        activeScreen.Show();
                        return true;
                    }
                }
            }
            return false;
        }

        private void HandleActionScreeenInput()
        {
            if (CheckKey(Keys.Escape))
            {
                playerSprite.IsAnimating = false;
                activeScreen.Enabled = false;
                activeScreen.Visible = false;
                activeScreen = startScreen;
                MediaPlayer.Stop();
                activeScreen.Show();
            }
            else if (CheckKey(Keys.V))
            {
                playerSprite.IsAnimating = false;
                activeScreen.Enabled = false;
                activeScreen = viewCharacterScreen;
                viewCharacterScreen.SetPlayerCharacter(playerCharacter);
                activeScreen.Show();
            }
        }

        private void HandleCreditScreenInput()
        {
            if (CheckKey(Keys.Enter))
            {
                activeScreen.Hide();
                activeScreen = startScreen;
                activeScreen.Show();
            }
        }

        private void HandleIntroScreenInput()
        {
            if (CheckKey(Keys.Escape) || CheckKey(Keys.Space) ||
            introScreen.IntroFinished)
            {
                activeScreen.Hide();
                activeScreen = startScreen;
                activeScreen.Show();
            }
        }

        private void HandleNameInputScreenInput()
        {
            if (CheckKey(Keys.Enter))
            {
                createPCScreen.ChangeName(nameInputScreen.Text);
                activeScreen.Hide();
                activeScreen = createPCScreen;
                activeScreen.Show();
            }
        }

        private void HandleDifficultyPopUpScreenInput()
        {
            if (CheckKey(Keys.Enter) || CheckKey(Keys.Space))
            {
                createPCScreen.ChangeDifficulty(
                difficultyPopUpScreen.SelectedIndex);
                activeScreen.Hide();
                activeScreen = createPCScreen;
                activeScreen.Show();
            }
        }

        private void HandleClassPopUpScreenInput()
        {
            if (CheckKey(Keys.Enter) || CheckKey(Keys.Space))
            {
                createPCScreen.ChangeClass(classPopUpScreen.SelectedIndex);
                activeScreen.Hide();
                activeScreen = createPCScreen;
                activeScreen.Show();
            }
        }

        private void HandleGenderPopUpScreenInput()
        {
            if (CheckKey(Keys.Enter) || CheckKey(Keys.Space))
            {
                switch (genderPopUpScreen.SelectedIndex)
                {
                    case 0:
                        createPCScreen.ChangeGender(true);
                        activeScreen.Hide();
                        activeScreen = createPCScreen;
                        activeScreen.Show();
                        break;
                    case 1:
                        createPCScreen.ChangeGender(false);
                        activeScreen.Hide();
                        activeScreen = createPCScreen;
                        activeScreen.Show();
                        break;
                }
            }
        }

        private void HandleGameOverScreenInput()
        {
            if (CheckKey(Keys.Enter) || CheckKey(Keys.Space))
            {
                this.Exit();
            }
        }

        private void HandleQuitPopUpScreenInput()
        {
            if (CheckKey(Keys.Enter) || CheckKey(Keys.Space))
            {
                switch (quitPopUpScreen.SelectedIndex)
                {
                    case 0:
                        this.Exit();
                        break;
                    case 1:
                        activeScreen.Hide();
                        activeScreen = startScreen;
                        activeScreen.Show();
                        break;
                }
            }
        }

        private void HandleHelpScreenInput()
        {
            if (CheckKey(Keys.Enter) || CheckKey(Keys.Space))
            {
                switch (helpScreen.SelectedIndex)
                {
                    case 0:
                        activeScreen.Hide();
                        activeScreen = startScreen;
                        activeScreen.Show();
                        break;
                }
            }
        }

        private void HandleStartScreenInput()
        {
            if (CheckKey(Keys.Enter) || CheckKey(Keys.Space))
            {
                switch (startScreen.SelectedIndex)
                {
                    case 0:
                        activeScreen.Hide();
                        activeScreen = createPCScreen;
                        activeScreen.Show();
                        break;
                    case 1:
                        activeScreen.Hide();
                        playerCharacter = new PirateCharacter(
                        "Big Cock",
                        false,
                        Level.Normal,
                        this);
                        playerSprite = new AnimatedSprite(this, playerTextures[0], ClonePlayerAnimations());
                        playerSprite.CurrentAnimation = AnimationKey.Down;
                        player = new PlayerComponent(this, playerSprite, playerCharacter);
                        activeScreen = actionScreen;
                        player.Show();
                        actionScreen.Show();
                        MediaPlayer.Play(mus);
                        break;
                    case 2:
                        activeScreen.Hide();
                        activeScreen = helpScreen;
                        activeScreen.Show();
                        break;
                    case 3:
                        activeScreen.Hide();
                        activeScreen = creditScreen;
                        activeScreen.Show();
                        break;
                    case 4:
                        activeScreen.Enabled = false;
                        activeScreen = quitPopUpScreen;
                        activeScreen.Show();
                        break;
                }
            }
        }

        private void HandleCreatePCScreenInput()
        {
            if (CheckKey(Keys.Enter) || CheckKey(Keys.Space))
            {
                switch (createPCScreen.SelectedIndex)
                {
                    case 0:
                        activeScreen.Enabled = false;
                        activeScreen = nameInputScreen;
                        activeScreen.Show();
                        break;
                    case 1:
                        activeScreen.Enabled = false;
                        activeScreen = genderPopUpScreen;
                        activeScreen.Show();
                        break;
                    case 2:
                        activeScreen.Enabled = false;
                        activeScreen = classPopUpScreen;
                        activeScreen.Show();
                        break;
                    case 3:
                        activeScreen.Enabled = false;
                        activeScreen = difficultyPopUpScreen;
                        activeScreen.Show();
                        break;
                    case 4:
                        activeScreen.Hide();
                        activeScreen = startScreen;
                        activeScreen.Show();
                        break;
                    case 5:
                        activeScreen.Hide();
                        CreatePlayerCharacter();
                        activeScreen = actionScreen;
                        activeScreen.Show();
                        MediaPlayer.Play(mus);
                        break;
                }
            }
        }

        private void HandleViewCharacterScreenInput()
        {
            if (CheckKey(Keys.Enter) || CheckKey(Keys.V))
            {
                activeScreen.Hide();
                activeScreen = actionScreen;
                actionScreen.Show();
            }
        }

        public static Camera Camera
        {
            get { return camera; }
        }

        private void CreatePlayerCharacter()
        {
            if (createPCScreen.CharacterClass == CharClass.Pirate)
            {
                playerCharacter = new PirateCharacter(
                createPCScreen.CharacterName,
                createPCScreen.CharacterGender,
                createPCScreen.DifficultyLevel, this);
            }
            if (createPCScreen.CharacterClass == CharClass.BountyHunter)
            {
                playerCharacter = new BountyHunterCharacter(
                createPCScreen.CharacterName,
                createPCScreen.CharacterGender,
                createPCScreen.DifficultyLevel, this);
            }
            if (createPCScreen.CharacterClass == CharClass.SlaveTrader)
            {
                playerCharacter = new SlaveTraderCharacter(
                createPCScreen.CharacterName,
                createPCScreen.CharacterGender,
                createPCScreen.DifficultyLevel, this);
            }
            playerSprite = new AnimatedSprite(this,
                playerTextures[(int)createPCScreen.CharacterClass],
                ClonePlayerAnimations());
            playerSprite.CurrentAnimation = AnimationKey.Down;
            player = new PlayerComponent(this, playerSprite, playerCharacter);
            player.Hide();
        }

        public static bool CheckKey(Keys theKey)
        {
            return oldState.IsKeyDown(theKey) && newState.IsKeyUp(theKey);
        }

        public static KeyboardState NewState
        {
            get { return newState; }
        }

        public static KeyboardState OldState
        {
            get { return oldState; }
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
            base.Draw(gameTime);
            if (activeScreen == actionScreen)
            {
                player.Draw(gameTime);
                foreach (NPC sprite in npcs)
                    sprite.Draw(gameTime);
                foreach (Monster monster in monsters)
                {
                    if (!monster.InCombat)
                        monster.Draw(gameTime);
                }

                itemManager.Draw(gameTime);
            }
            spriteBatch.End();
        }

        public static SpriteBatch TileSpriteBatch
        {
            get { return tileSpriteBatch; }
        }

        private void CreateAnimations()
        {
            Animation tempAnimation = new Animation(2, 64, 64, 0, 0);
            animations.Add(tempAnimation);
            tempAnimation = new Animation(2, 64, 64, 128, 0);
            animations.Add(tempAnimation);
            tempAnimation = new Animation(2, 64, 64, 256, 0);
            animations.Add(tempAnimation);
            tempAnimation = new Animation(2, 64, 64, 384, 0);
            animations.Add(tempAnimation);
        }

        private List<Animation> CloneAnimations()
        {
            List<Animation> newAnimation = new List<Animation>();
            foreach (Animation a in animations)
            {
                Animation clonedAnimation = (Animation)a.Clone();
                newAnimation.Add(clonedAnimation);
            }
            return newAnimation;
        }

        private void CreateMonsters()
        {
            for (int i = 0; i < 2; i++)
            {
                Monster monster = new Monster(
                this,
                Content.Load<Texture2D>(@"Sprites\thf1"),
                CloneAnimations(), 10, 40, 1);
                int direction = random.Next(0, 4);
                switch (direction)
                {
                    case 0:
                        monster.CurrentAnimation = AnimationKey.Up;
                        break;
                    case 1:
                        monster.CurrentAnimation = AnimationKey.Down;
                        break;
                    case 2:
                        monster.CurrentAnimation = AnimationKey.Left;
                        break;
                    case 3:
                        monster.CurrentAnimation = AnimationKey.Right;
                        break;
                }
                Vector2 position = new Vector2();
                position.X = TileEngine.TileWidth * random.Next(1, 10);
                position.Y = TileEngine.TileHeight * random.Next(1, 10);
                monster.IsAnimating = true;
                monster.Position = position;
                monsters.Add(monster);
            }
        }

        

    }
}